import md5 from "md5";
// @ts-ignore
import CryptoJS from "crypto-js";

class RequestInterception {
    private requestInits: ReqInit[] = [];
    static onloadMessage: any[] = [];
    static onListen = false;
    static onLoadListener = (ev: any) => {
        if (!RequestInterception.onListen) {
            if (typeof ev.data.type !== 'undefined' && ev.data.type === 'xc_fetch') {
                RequestInterception.onloadMessage.push(ev);
            }
        }
    };
    private data: any = {};
    public listener: Function = (ev: MessageEvent<any>): any => {
        if (typeof ev.data.type !== 'undefined' && ev.data.type === 'xc_fetch') {
            // 判断requestInits是否有对应的需要拦截的请求
            let _requestInit: ReqInit = ev.data.options;
            // 对请求的参数进行整理
            let params: any = {};
            let ps = ev.data.options.url.split('?');
            if (ps.length > 1) {
                ps[1].split('&').forEach((item: string) => {
                    let _ps = item.split('=');
                    params[_ps[0]] = _ps[1];
                });
            }
            // console.log(ev.data.options.url,params);
            let requestInit = this.requestInits.find((item: ReqInit | any) => {
                if (!_requestInit.url.includes(item.url)) {
                    return false;
                }
                if (typeof item.params !== 'undefined') {
                    // console.log(item.params,_requestInit.params,_requestInit.url,item.url);
                    if (typeof _requestInit.params !== 'undefined') {
                        for (let key in item.params) {
                            if (typeof params[key] == "undefined" || item.params[key] != params[key]) {
                                return false;
                            }
                        }
                        return true;
                    }
                } else {
                    return true;
                }
            });
            if (typeof requestInit !== 'undefined') {
                this.data[md5(JSON.stringify(requestInit))] = ev.data.response;
                this.data['_' + md5(JSON.stringify(requestInit))] = ev.data.options;
            }
        }
    };

    constructor(requestInits: ReqInit[] = []) {
        this.requestInits = requestInits;
        // @ts-ignore
        window.addEventListener('message', this.listener);
        RequestInterception.onloadMessage.forEach(ev => {
            window.postMessage(ev.data);
        })
        RequestInterception.onListen = true;
    }

    getResponse(requestInit: ReqInit, type: string = 'json', includeUrl: string | Array<string> = '') {
        let data: any = null;
        // let data = this.data[md5(JSON.stringify(requestInit))] || null;
        // if (data === null || typeof JSON.parse(data)['url'] !== 'undefined') {
        if (includeUrl){
            const keys = Object.keys(localStorage).filter((item: string) => {
                return item.includes(requestInit.url)
            });
            const items = keys.map((item: string) => {
                let data = localStorage.getItem(item);
                let _data: string = data || '';
                let d = _data.split('|');
                if (d.length > 1) {
                    // 去除d[1]中头尾的双引号
                    d[1] = d[1].replace(/^\"|\"$/g, "");
                    // 去除转义
                    d[1] = d[1].replace(/\\\"/g, "\"");
                    return (JSON.parse(d[1])).value._d;
                } else {
                    return null;
                }
            });
            // 从items中获取最长的数据
            let key = '';
            // 倒序从items中获取最长的数据
            for (let i = items.length - 1; i >= 0; i--) {
                if (items[i] !== null) {
                    if (typeof includeUrl === 'string') {
                        if (!keys[i].includes(includeUrl)) {
                            continue;
                        }
                    } else {
                        // includeUrl是数组 items[i] 包含所有的includeUrl
                        let flag = true;
                        for (let j = 0; j < includeUrl.length; j++) {
                            if (!keys[i].includes(includeUrl[j])) {
                                flag = false;
                                break;
                            }
                        }
                        if (!flag) {
                            continue;
                        }
                    }
                    key = keys[i];
                    break;
                }
            }
            // console.log(key,localStorage.getItem(key));
            if (keys.length > 0) {
                if (key !== undefined) {
                    let _data: string = localStorage.getItem(key) || '';
                    let d = _data.split('|');
                    if (d.length > 1) {
                        // 去除d[1]中头尾的双引号
                        d[1] = d[1].replace(/^\"|\"$/g, "");
                        // 去除转义
                        d[1] = d[1].replace(/\\\"/g, "\"");
                        data = JSON.stringify({
                            data: (JSON.parse(d[1])).value._d,
                        });
                    }
                } else {
                    return null;
                }
            }
        }else {
            data = this.data[md5(JSON.stringify(requestInit))] || null;
        }

        // }
        // if (data === null && !includeUrl) {
        //     data = this.data[md5(JSON.stringify(requestInit))] || null;
        // }
        if (type === 'json') {
            data = JSON.parse(data);
            if (!data) {
                return null;
            }
            if (typeof data.data === "string") {
                // 密钥
                let key = 'w28Cz694s63kBYk4';
                let iv = '4kYBk36s496zC82w';
                const encryptedHexStr = CryptoJS.enc.Hex.parse(data.data) // 把密文由 128 bit 转为十六进制
                const encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr) // 再转为 Base64 编码的字符串
                const formatedKey = CryptoJS.enc.Utf8.parse(key) // 将 key 转为 128bit 格式
                const formatedIv = CryptoJS.enc.Utf8.parse(iv) // 将 iv 转为 128bit 格式
                const decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, formatedKey, {
                    iv: formatedIv,
                    mode: CryptoJS.mode.CBC,
                    padding: CryptoJS.pad.Pkcs7
                })
                // 解密
                data.data = decryptedData.toString(CryptoJS.enc.Utf8) // 经过 AES 解密后，依然是一个对象，将其变成明文就需要按照 Utf8
                try {
                    data.data = JSON.parse(data.data);
                } catch (e) {
                    data.data = null;
                }
            }
            data.__options = this.data['_' + md5(JSON.stringify(requestInit))];
            return data;
        }
        return data;
    }

    removeListener() {
        // @ts-ignore
        window.removeEventListener('message', this.listener);
    }

    destroy() {
        this.removeListener();
    }
}

export default RequestInterception;
